/**
 * @file:          ch32v30x_module_v11.c
 * @brief:
 * @details:
 * @author:        wjh
 * @date created:  2023.06.09
 * @version:       1.0.0
 * @par copyright (c):
 *
 * @par history (desc):
 *   version:1.0.0, wjh, 2023.06.09,18:31:30
 */
/* Include Files **************************************************************/
#include "ch32v30x_module.h"
#include "ch32v30x_module_v11.h"
#include "stdio.h"
#include "common.h"
#include "stdlib.h"
#include "string.h"

/* Global Variable Define *****************************************************/
extern int8 UartRxBuff[UART_RX_FIFO_SIZE];

/* Function Define ************************************************************/
uint8 ch32v30x_module_v11_Init(ch32v30x_module *self)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

    /* init class method pointer */
    self->InitSystem = ch32v30x_module_v11_InitSystem;
    self->InitClock = ch32v30x_module_v11_InitClock;
    self->InitGpio = ch32v30x_module_v11_InitGpio;
    self->InitAdc = ch32v30x_module_v11_InitAdc;
    self->InitUart = ch32v30x_module_v11_InitUart;
    self->InitDMA = ch32v30x_module_v11_InitDMA;
    self->InitPwm = ch32v30x_module_v11_InitPwm;
    self->InitTimmer = ch32v30x_module_v11_InitTimmer;
    self->InitSpi = ch32v30x_module_v11_InitSpi;
    self->InitInternalFlash = ch32v30x_module_v11_InitInternalFlash;
    self->InitInputPulseCounter = ch32v30x_module_v11_InitInputPulseCounter;
    self->InitExternalInterrupt = ch32v30x_module_v11_InitExternalInterrupt;
    self->InitIWDG = ch32v30x_module_v11_InitIWDG;
    self->InitWWDG = ch32v30x_module_v11_InitWWDG;
    self->InitDelay = ch32v30x_module_v11_InitDelay;
    self->GpioToggle = ch32v30x_module_v11_GpioToggle;
    self->GpioSet = ch32v30x_module_v11_GpioSet;
    self->GpioReset = ch32v30x_module_v11_GpioReset;
    self->GpioRead = ch32v30x_module_v11_GpioRead;
    self->DelayMs = ch32v30x_module_v11_DelayMs;
    self->DelayUs = ch32v30x_module_v11_DelayUs;
    self->AdcGetResult = ch32v30x_module_v11_AdcGetResult;
    self->StartTimmer = ch32v30x_module_v11_StartTimmer;
    self->StopTimmer = ch32v30x_module_v11_StopTimmer;
    self->GpioPinInit = ch32v30x_module_v11_GpioPinInit;
    self->GpioModeTranslate = ch32v30x_module_v11_GpioModeTranslate;
    self->SetPwm = ch32v30x_module_v11_SetPwm;
    self->SetAllPwm = ch32v30x_module_v11_SetAllPwm;
    self->SPI_WriteReadData = ch32v30x_module_v11_SPI_WriteReadData;
    self->SPI_WriteReg = ch32v30x_module_v11_SPI_WriteReg;
    self->SPI_ReadReg = ch32v30x_module_v11_SPI_ReadReg;
    self->SPI_WriteByte = ch32v30x_module_v11_SPI_WriteByte;
    self->SPI_ReadByte = ch32v30x_module_v11_SPI_ReadByte;
    self->EnableInterrupt = ch32v30x_module_v11_EnableInterrupt;
    self->EnableNvicInterrupt = ch32v30x_module_v11_EnableNvicInterrupt;
    self->DisableNvicInterrupt = ch32v30x_module_v11_DisableNvicInterrupt;
    self->ADC_StartConversion = ch32v30x_module_v11_ADC_StartConversion;
    self->ADC_WaitConversionComplete = ch32v30x_module_v11_ADC_WaitConversionComplete;
    self->FlashWriteOnePage256Bytes = ch32v30x_module_v11_FlashWriteOnePage256Bytes;
    self->FlashWriteHalfWord = ch32v30x_module_v11_FlashWriteHalfWord;
    self->FlashEraseOnePage256Bytes_Fast = ch32v30x_module_v11_FlashEraseOnePage256Bytes_Fast;
    self->FlashEraseOnePage32KBytes_Fast = ch32v30x_module_v11_FlashEraseOnePage32KBytes_Fast;
    self->FlashEraseOnePage32KBytes = ch32v30x_module_v11_FlashEraseOnePage32KBytes;
    self->FlashUnlockFast = ch32v30x_module_v11_FlashUnlockFast;
    self->FlashLockFast = ch32v30x_module_v11_FlashLockFast;
    self->FlashUnlock = ch32v30x_module_v11_FlashUnlock;
    self->FlashLock = ch32v30x_module_v11_FlashLock;
    self->FlashClearFlag = ch32v30x_module_v11_FlashClearFlag;
    self->GetInputPulseCounter = ch32v30x_module_v11_GetInputPulseCounter;
    self->ClearInputPulseCounter = ch32v30x_module_v11_ClearInputPulseCounter;
    self->SetInputPulseCounter = ch32v30x_module_v11_SetInputPulseCounter;
    self->AddInputPulseCounter = ch32v30x_module_v11_AddInputPulseCounter;
    self->EnableInputPulseCounter = ch32v30x_module_v11_EnableInputPulseCounter;
    self->DisableInputPulseCounter = ch32v30x_module_v11_DisableInputPulseCounter;
    self->StartUartDMA = ch32v30x_module_v11_StartUartDMA;
    self->UartReceiveOnePackFinished = ch32v30x_module_v11_UartReceiveOnePackFinished;
    self->ResetSystem = ch32v30x_module_v11_ResetSystem;
    self->InitPinNum = ch32v30x_module_v11_InitPinNum;
    self->UartDMASend = ch32v30x_module_v11_UartDMASend;
    self->SetInputPulseCouterCountUp = ch32v30x_module_v11_SetInputPulseCouterCountUp;
    self->SetInputPulseCouterCountDown = ch32v30x_module_v11_SetInputPulseCouterCountDown;
    self->EnableIWDG = ch32v30x_module_v11_EnableIWDG;
    self->EnableWWDG = ch32v30x_module_v11_EnableWWDG;
    self->FeedIWDG = ch32v30x_module_v11_FeedIWDG;
    self->FeedWWDG = ch32v30x_module_v11_FeedWWDG;
    self->UartSendOneByte = ch32v30x_module_v11_UartSendOneByte;
    self->DMA_Send = ch32v30x_module_v11_DMA_Send;
    self->DMAAdv_Send = ch32v30x_module_v11_DMAAdv_Send;
    self->DMAHex_Send = ch32v30x_module_v11_DMAHex_Send;
    self->JumpToBootLoader = ch32v30x_module_v11_JumpToBootLoader;
    self->HCLKSetToDiv1 = ch32v30x_module_v11_HCLKSetToDiv1;
    self->HCLKSetToDiv2 = ch32v30x_module_v11_HCLKSetToDiv2;

    self->sysclk_hz = self->param_sysclk_hz;
    
    /* init pin */
    self->InitPinNum(self);

    /* init system */
    // self->InitSystem(self);
    self->InitClock(self);
    self->InitUart(self);
    self->InitDMA(self);
    self->InitInternalFlash(self);
    self->InitGpio(self);
    self->InitAdc(self);
    self->InitPwm(self);
    self->InitTimmer(self);
    self->InitSpi(self);
    self->InitInputPulseCounter(self);
    self->InitExternalInterrupt(self);
    self->InitIWDG(self);
    self->InitWWDG(self);
    self->InitDelay(self);

    return TRUE;
}

void ch32v30x_module_v11_InitSystem(ch32v30x_module *self)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

#ifndef HARDWARE_DISABLE
    /* System Init */
    RCC->CTLR |= (uint32_t)0x00000001;

#ifdef CH32V30x_D8C
    RCC->CFGR0 &= (uint32_t)0xF8FF0000;
#else
    RCC->CFGR0 &= (uint32_t)0xF0FF0000;
#endif

    RCC->CTLR &= (uint32_t)0xFEF6FFFF;
    RCC->CTLR &= (uint32_t)0xFFFBFFFF;
    RCC->CFGR0 &= (uint32_t)0xFF80FFFF;

#ifdef CH32V30x_D8C
    RCC->CTLR &= (uint32_t)0xEBFFFFFF;
    RCC->INTR = 0x00FF0000;
    RCC->CFGR2 = 0x00000000;
#else
    RCC->INTR = 0x009F0000;
#endif

    // SystemCoreClockUpdate();
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    // Delay_Init();
#endif
}

void ch32v30x_module_v11_InitClock(ch32v30x_module *self)
{
#ifndef HARDWARE_DISABLE
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

    /* Init Clock */
    self->pll_mull = self->sysclk_hz / self->param_HSE_hz;
    if (self->pll_mull >= 2)
    {
        self->pll_mull_reg = (self->pll_mull - 2UL) << 18;
    }
    else
    {
        self->pll_mull_reg = 0;
    }

    /*  */
    __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

    RCC->CTLR |= ((uint32_t)RCC_HSEON);

    /* Wait till HSE is ready and if Time out is reached exit */
    do
    {
        HSEStatus = RCC->CTLR & RCC_HSERDY;
        StartUpCounter++;
    } while ((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

    if ((RCC->CTLR & RCC_HSERDY) != RESET)
    {
        HSEStatus = (uint32_t)0x01;
    }
    else
    {
        HSEStatus = (uint32_t)0x00;
    }

    if (HSEStatus == (uint32_t)0x01)
    {
        /* HCLK = SYSCLK */
        RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
        /* PCLK2 = HCLK */
        RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
        /* PCLK1 = HCLK */
        RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;

        /*  PLL configuration: PLLCLK = HSE * 18 = 144 MHz */
        RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
                                              RCC_PLLMULL));

#ifdef CH32V30x_D8
        RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | self->pll_mull_reg);
#else
        RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18_EXTEN);
#endif

        /* Enable PLL */
        RCC->CTLR |= RCC_PLLON;
        /* Wait till PLL is ready */
        while ((RCC->CTLR & RCC_PLLRDY) == 0)
        {
        }
        /* Select PLL as system clock source */
        RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
        RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
        /* Wait till PLL is used as system clock source */
        while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
        {
        }
    }
    else
    {
        /*
         * If HSE fails to start-up, the application will have wrong clock
         * configuration. User can add here some code to deal with this error
         */
    }

    /* Set Clock */
    const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};

    uint32_t Pll_6_5 = 0;

    self->rcc_sws = RCC->CFGR0 & RCC_SWS;

    switch (self->rcc_sws)
    {
    case 0x00:
        self->sysclk_hz = HSI_VALUE;
        break;
    case 0x04:
        self->sysclk_hz = self->param_HSE_hz;
        break;
    case 0x08:
        self->pll_mull = RCC->CFGR0 & RCC_PLLMULL;
        self->pll_source = RCC->CFGR0 & RCC_PLLSRC;
        self->pll_mull = (self->pll_mull >> 18) + 2;

#ifdef CH32V30x_D8
        if (self->pll_mull == 17)
            self->pll_mull = 18;
#else
        if (self->pll_mull == 2)
            self->pll_mull = 18;
        if (self->pll_mull == 15)
        {
            self->pll_mull = 13; /* *6.5 */
            Pll_6_5 = 1;
        }
        if (self->pll_mull == 16)
            self->pll_mull = 15;
        if (self->pll_mull == 17)
            self->pll_mull = 16;
#endif

        if (self->pll_source == 0x00)
        {
            if (EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE)
            {
                self->sysclk_hz = (HSI_VALUE)*self->pll_mull;
            }
            else
            {
                self->sysclk_hz = (HSI_VALUE >> 1) * self->pll_mull;
            }
        }
        else
        {
            if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET)
            {
                self->sysclk_hz = (self->param_HSE_hz >> 1) * self->pll_mull;
            }
            else
            {
                self->sysclk_hz = self->param_HSE_hz * self->pll_mull;
            }
        }

        if (Pll_6_5 == 1)
            self->sysclk_hz = (self->sysclk_hz / 2);

        break;
    default:
        self->sysclk_hz = HSI_VALUE;
        break;
    }

    self->rcc_hpre = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)];
    self->sysclk_hz >>= self->rcc_hpre;
#endif
}

void ch32v30x_module_v11_InitGpio(ch32v30x_module *self)
{

#ifndef HARDWARE_DISABLE
    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

    if ((NULL != _->param_pin_PA0) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA0->mode))
        self->GpioPinInit(self, _->param_pin_PA0->pin, _->param_pin_PA0->mode);
    if ((NULL != _->param_pin_PA1) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA1->mode))
        self->GpioPinInit(self, _->param_pin_PA1->pin, _->param_pin_PA1->mode);
    if ((NULL != _->param_pin_PA2) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA2->mode))
        self->GpioPinInit(self, _->param_pin_PA2->pin, _->param_pin_PA2->mode);
    if ((NULL != _->param_pin_PA3) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA3->mode))
        self->GpioPinInit(self, _->param_pin_PA3->pin, _->param_pin_PA3->mode);
    if ((NULL != _->param_pin_PA4) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA4->mode))
        self->GpioPinInit(self, _->param_pin_PA4->pin, _->param_pin_PA4->mode);
    if ((NULL != _->param_pin_PA5) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA5->mode))
        self->GpioPinInit(self, _->param_pin_PA5->pin, _->param_pin_PA5->mode);
    if ((NULL != _->param_pin_PA6) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA6->mode))
        self->GpioPinInit(self, _->param_pin_PA6->pin, _->param_pin_PA6->mode);
    if ((NULL != _->param_pin_PA7) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA7->mode))
        self->GpioPinInit(self, _->param_pin_PA7->pin, _->param_pin_PA7->mode);
    if ((NULL != _->param_pin_PA8) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA8->mode))
        self->GpioPinInit(self, _->param_pin_PA8->pin, _->param_pin_PA8->mode);
    if ((NULL != _->param_pin_PA9) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA9->mode))
        self->GpioPinInit(self, _->param_pin_PA9->pin, _->param_pin_PA9->mode);
    if ((NULL != _->param_pin_PA10) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA10->mode))
        self->GpioPinInit(self, _->param_pin_PA10->pin, _->param_pin_PA10->mode);
    if ((NULL != _->param_pin_PA11) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA11->mode))
        self->GpioPinInit(self, _->param_pin_PA11->pin, _->param_pin_PA11->mode);
    if ((NULL != _->param_pin_PA12) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA12->mode))
        self->GpioPinInit(self, _->param_pin_PA12->pin, _->param_pin_PA12->mode);
    if ((NULL != _->param_pin_PA13) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA13->mode))
        self->GpioPinInit(self, _->param_pin_PA13->pin, _->param_pin_PA13->mode);
    if ((NULL != _->param_pin_PA14) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA14->mode))
        self->GpioPinInit(self, _->param_pin_PA14->pin, _->param_pin_PA14->mode);
    if ((NULL != _->param_pin_PA15) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PA15->mode))
        self->GpioPinInit(self, _->param_pin_PA15->pin, _->param_pin_PA15->mode);

    if ((NULL != _->param_pin_PB0) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB0->mode))
        self->GpioPinInit(self, _->param_pin_PB0->pin, _->param_pin_PB0->mode);
    if ((NULL != _->param_pin_PB1) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB1->mode))
        self->GpioPinInit(self, _->param_pin_PB1->pin, _->param_pin_PB1->mode);
    if ((NULL != _->param_pin_PB2) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB2->mode))
        self->GpioPinInit(self, _->param_pin_PB2->pin, _->param_pin_PB2->mode);
    if ((NULL != _->param_pin_PB3) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB3->mode))
        self->GpioPinInit(self, _->param_pin_PB3->pin, _->param_pin_PB3->mode);
    if ((NULL != _->param_pin_PB4) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB4->mode))
        self->GpioPinInit(self, _->param_pin_PB4->pin, _->param_pin_PB4->mode);
    if ((NULL != _->param_pin_PB5) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB5->mode))
        self->GpioPinInit(self, _->param_pin_PB5->pin, _->param_pin_PB5->mode);
    if ((NULL != _->param_pin_PB6) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB6->mode))
        self->GpioPinInit(self, _->param_pin_PB6->pin, _->param_pin_PB6->mode);
    if ((NULL != _->param_pin_PB7) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB7->mode))
        self->GpioPinInit(self, _->param_pin_PB7->pin, _->param_pin_PB7->mode);
    if ((NULL != _->param_pin_PB8) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB8->mode))
        self->GpioPinInit(self, _->param_pin_PB8->pin, _->param_pin_PB8->mode);
    if ((NULL != _->param_pin_PB9) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB9->mode))
        self->GpioPinInit(self, _->param_pin_PB9->pin, _->param_pin_PB9->mode);
    if ((NULL != _->param_pin_PB10) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB10->mode))
        self->GpioPinInit(self, _->param_pin_PB10->pin, _->param_pin_PB10->mode);
    if ((NULL != _->param_pin_PB11) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB11->mode))
        self->GpioPinInit(self, _->param_pin_PB11->pin, _->param_pin_PB11->mode);
    if ((NULL != _->param_pin_PB12) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB12->mode))
        self->GpioPinInit(self, _->param_pin_PB12->pin, _->param_pin_PB12->mode);
    if ((NULL != _->param_pin_PB13) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB13->mode))
        self->GpioPinInit(self, _->param_pin_PB13->pin, _->param_pin_PB13->mode);
    if ((NULL != _->param_pin_PB14) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB14->mode))
        self->GpioPinInit(self, _->param_pin_PB14->pin, _->param_pin_PB14->mode);
    if ((NULL != _->param_pin_PB15) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PB15->mode))
        self->GpioPinInit(self, _->param_pin_PB15->pin, _->param_pin_PB15->mode);

    if ((NULL != _->param_pin_PC0) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC0->mode))
        self->GpioPinInit(self, _->param_pin_PC0->pin, _->param_pin_PC0->mode);
    if ((NULL != _->param_pin_PC1) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC1->mode))
        self->GpioPinInit(self, _->param_pin_PC1->pin, _->param_pin_PC1->mode);
    if ((NULL != _->param_pin_PC2) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC2->mode))
        self->GpioPinInit(self, _->param_pin_PC2->pin, _->param_pin_PC2->mode);
    if ((NULL != _->param_pin_PC3) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC3->mode))
        self->GpioPinInit(self, _->param_pin_PC3->pin, _->param_pin_PC3->mode);
    if ((NULL != _->param_pin_PC4) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC4->mode))
        self->GpioPinInit(self, _->param_pin_PC4->pin, _->param_pin_PC4->mode);
    if ((NULL != _->param_pin_PC5) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC5->mode))
        self->GpioPinInit(self, _->param_pin_PC5->pin, _->param_pin_PC5->mode);
    if ((NULL != _->param_pin_PC6) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC6->mode))
        self->GpioPinInit(self, _->param_pin_PC6->pin, _->param_pin_PC6->mode);
    if ((NULL != _->param_pin_PC7) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC7->mode))
        self->GpioPinInit(self, _->param_pin_PC7->pin, _->param_pin_PC7->mode);
    if ((NULL != _->param_pin_PC8) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC8->mode))
        self->GpioPinInit(self, _->param_pin_PC8->pin, _->param_pin_PC8->mode);
    if ((NULL != _->param_pin_PC9) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC9->mode))
        self->GpioPinInit(self, _->param_pin_PC9->pin, _->param_pin_PC9->mode);
    if ((NULL != _->param_pin_PC10) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC10->mode))
        self->GpioPinInit(self, _->param_pin_PC10->pin, _->param_pin_PC10->mode);
    if ((NULL != _->param_pin_PC11) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC11->mode))
        self->GpioPinInit(self, _->param_pin_PC11->pin, _->param_pin_PC11->mode);
    if ((NULL != _->param_pin_PC12) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC12->mode))
        self->GpioPinInit(self, _->param_pin_PC12->pin, _->param_pin_PC12->mode);
    if ((NULL != _->param_pin_PC13) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC13->mode))
        self->GpioPinInit(self, _->param_pin_PC13->pin, _->param_pin_PC13->mode);
    if ((NULL != _->param_pin_PC14) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC14->mode))
        self->GpioPinInit(self, _->param_pin_PC14->pin, _->param_pin_PC14->mode);
    if ((NULL != _->param_pin_PC15) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PC15->mode))
        self->GpioPinInit(self, _->param_pin_PC15->pin, _->param_pin_PC15->mode);

    if ((NULL != _->param_pin_PD0) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD0->mode))
        self->GpioPinInit(self, _->param_pin_PD0->pin, _->param_pin_PD0->mode);
    if ((NULL != _->param_pin_PD1) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD1->mode))
        self->GpioPinInit(self, _->param_pin_PD1->pin, _->param_pin_PD1->mode);
    if ((NULL != _->param_pin_PD2) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD2->mode))
        self->GpioPinInit(self, _->param_pin_PD2->pin, _->param_pin_PD2->mode);
    if ((NULL != _->param_pin_PD3) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD3->mode))
        self->GpioPinInit(self, _->param_pin_PD3->pin, _->param_pin_PD3->mode);
    if ((NULL != _->param_pin_PD4) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD4->mode))
        self->GpioPinInit(self, _->param_pin_PD4->pin, _->param_pin_PD4->mode);
    if ((NULL != _->param_pin_PD5) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD5->mode))
        self->GpioPinInit(self, _->param_pin_PD5->pin, _->param_pin_PD5->mode);
    if ((NULL != _->param_pin_PD6) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD6->mode))
        self->GpioPinInit(self, _->param_pin_PD6->pin, _->param_pin_PD6->mode);
    if ((NULL != _->param_pin_PD7) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD7->mode))
        self->GpioPinInit(self, _->param_pin_PD7->pin, _->param_pin_PD7->mode);
    if ((NULL != _->param_pin_PD8) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD8->mode))
        self->GpioPinInit(self, _->param_pin_PD8->pin, _->param_pin_PD8->mode);
    if ((NULL != _->param_pin_PD9) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD9->mode))
        self->GpioPinInit(self, _->param_pin_PD9->pin, _->param_pin_PD9->mode);
    if ((NULL != _->param_pin_PD10) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD10->mode))
        self->GpioPinInit(self, _->param_pin_PD10->pin, _->param_pin_PD10->mode);
    if ((NULL != _->param_pin_PD11) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD11->mode))
        self->GpioPinInit(self, _->param_pin_PD11->pin, _->param_pin_PD11->mode);
    if ((NULL != _->param_pin_PD12) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD12->mode))
        self->GpioPinInit(self, _->param_pin_PD12->pin, _->param_pin_PD12->mode);
    if ((NULL != _->param_pin_PD13) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD13->mode))
        self->GpioPinInit(self, _->param_pin_PD13->pin, _->param_pin_PD13->mode);
    if ((NULL != _->param_pin_PD14) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD14->mode))
        self->GpioPinInit(self, _->param_pin_PD14->pin, _->param_pin_PD14->mode);
    if ((NULL != _->param_pin_PD15) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PD15->mode))
        self->GpioPinInit(self, _->param_pin_PD15->pin, _->param_pin_PD15->mode);

    if ((NULL != _->param_pin_PE0) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE0->mode))
        self->GpioPinInit(self, _->param_pin_PE0->pin, _->param_pin_PE0->mode);
    if ((NULL != _->param_pin_PE1) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE1->mode))
        self->GpioPinInit(self, _->param_pin_PE1->pin, _->param_pin_PE1->mode);
    if ((NULL != _->param_pin_PE2) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE2->mode))
        self->GpioPinInit(self, _->param_pin_PE2->pin, _->param_pin_PE2->mode);
    if ((NULL != _->param_pin_PE3) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE3->mode))
        self->GpioPinInit(self, _->param_pin_PE3->pin, _->param_pin_PE3->mode);
    if ((NULL != _->param_pin_PE4) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE4->mode))
        self->GpioPinInit(self, _->param_pin_PE4->pin, _->param_pin_PE4->mode);
    if ((NULL != _->param_pin_PE5) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE5->mode))
        self->GpioPinInit(self, _->param_pin_PE5->pin, _->param_pin_PE5->mode);
    if ((NULL != _->param_pin_PE6) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE6->mode))
        self->GpioPinInit(self, _->param_pin_PE6->pin, _->param_pin_PE6->mode);
    if ((NULL != _->param_pin_PE7) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE7->mode))
        self->GpioPinInit(self, _->param_pin_PE7->pin, _->param_pin_PE7->mode);
    if ((NULL != _->param_pin_PE8) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE8->mode))
        self->GpioPinInit(self, _->param_pin_PE8->pin, _->param_pin_PE8->mode);
    if ((NULL != _->param_pin_PE9) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE9->mode))
        self->GpioPinInit(self, _->param_pin_PE9->pin, _->param_pin_PE9->mode);
    if ((NULL != _->param_pin_PE10) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE10->mode))
        self->GpioPinInit(self, _->param_pin_PE10->pin, _->param_pin_PE10->mode);
    if ((NULL != _->param_pin_PE11) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE11->mode))
        self->GpioPinInit(self, _->param_pin_PE11->pin, _->param_pin_PE11->mode);
    if ((NULL != _->param_pin_PE12) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE12->mode))
        self->GpioPinInit(self, _->param_pin_PE12->pin, _->param_pin_PE12->mode);
    if ((NULL != _->param_pin_PE13) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE13->mode))
        self->GpioPinInit(self, _->param_pin_PE13->pin, _->param_pin_PE13->mode);
    if ((NULL != _->param_pin_PE14) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE14->mode))
        self->GpioPinInit(self, _->param_pin_PE14->pin, _->param_pin_PE14->mode);
    if ((NULL != _->param_pin_PE15) && (GPIO_GENERAL_MODE_NULL != _->param_pin_PE15->mode))
        self->GpioPinInit(self, _->param_pin_PE15->pin, _->param_pin_PE15->mode);

#endif
}

void ch32v30x_module_v11_InitAdc(ch32v30x_module *self)
{
#ifndef HARDWARE_DISABLE
    /* init motor current fdb adc */
    // ch32v30x_module_v11 *_ = (ch32v30x_module_v12 *)self->_;
    ADC_InitTypeDef ADC_InitStructure = {0};
    GPIO_InitTypeDef GPIO_InitStructure = {0};

    /* clock config */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div8);

    /* adc param config */
    /* adc1 init */
    ADC_DeInit(ADC1);
    ADC_InitStructure.ADC_Mode = ADC_Mode_InjecSimult;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigInjecConv_None; // ADC_ExternalTrigInjecConv_T1_TRGO;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 3;
    ADC_InitStructure.ADC_OutputBuffer = ADC_OutputBuffer_Disable;
    ADC_InitStructure.ADC_Pga = ADC_Pga_1;

    ADC_Init(ADC1, &ADC_InitStructure);
    ADC_InjectedSequencerLengthConfig(ADC1, 3);
    ADC_InjectedChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_28Cycles5);
    ADC_InjectedChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_239Cycles5);
    ADC_InjectedChannelConfig(ADC1, ADC_Channel_17, 3, ADC_SampleTime_239Cycles5);

    // ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T1_TRGO);
    // ADC_ExternalTrigInjectedConvCmd(ADC1, ENABLE);

    ADC_DMACmd(ADC1, ENABLE);
    // ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);
    ADC_Cmd(ADC1, ENABLE);

    ADC_BufferCmd(ADC1, DISABLE); // disable buffer
    ADC_ResetCalibration(ADC1);
    while (ADC_GetResetCalibrationStatus(ADC1))
        ;
    ADC_StartCalibration(ADC1);
    while (ADC_GetCalibrationStatus(ADC1))
        ;
    self->adc1_offset = Get_CalibrationValue(ADC1);

    // ADC_BufferCmd(ADC1, ENABLE);   //enable buffer

    /* adc2 init */
    ADC_DeInit(ADC2);
    ADC_InitStructure.ADC_Mode = ADC_Mode_InjecSimult;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigInjecConv_None; // ADC_ExternalTrigInjecConv_T1_TRGO;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 2;
    ADC_InitStructure.ADC_OutputBuffer = ADC_OutputBuffer_Disable;
    ADC_InitStructure.ADC_Pga = ADC_Pga_1;

    ADC_Init(ADC2, &ADC_InitStructure);
    ADC_InjectedSequencerLengthConfig(ADC2, 2);
    ADC_InjectedChannelConfig(ADC2, ADC_Channel_2, 1, ADC_SampleTime_28Cycles5);
    ADC_InjectedChannelConfig(ADC2, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5);

    // ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 );

    // ADC_ExternalTrigInjectedConvConfig(ADC2, ADC_ExternalTrigInjecConv_None);
    ADC_SoftwareStartInjectedConvCmd(ADC2, ENABLE);

    ADC_Cmd(ADC2, ENABLE);

    ADC_BufferCmd(ADC2, DISABLE); // disable buffer
    ADC_ResetCalibration(ADC2);
    while (ADC_GetResetCalibrationStatus(ADC2))
        ;
    ADC_StartCalibration(ADC2);
    while (ADC_GetCalibrationStatus(ADC2))
        ;
    self->adc2_offset = Get_CalibrationValue(ADC2);

    // ADC_BufferCmd(ADC2, ENABLE);   //enable buffer

    /* init power voltage fdb adc */
    ADC_TempSensorVrefintCmd(ENABLE);

#endif
}

void ch32v30x_module_v11_InitUart(ch32v30x_module *self)
{
#ifndef HARDWARE_DISABLE
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;
    //    GPIO_InitTypeDef GPIO_InitStructure = {0};
    USART_InitTypeDef USART_InitStructure = {0};
    //    NVIC_InitTypeDef NVIC_InitStructure = {0};

#if UART_NUM_USED == 1

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);

#elif UART_NUM_USED == 3

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

#endif

    // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    // GPIO_Init(GPIOA, &GPIO_InitStructure);
    // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    // GPIO_Init(GPIOA, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate = self->param_uart_baudrate;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;

    USART_Init(USART_USED, &USART_InitStructure);

    // NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    // NVIC_Init(&NVIC_InitStructure);

    USART_Cmd(USART_USED, ENABLE);
#endif
}

void ch32v30x_module_v11_InitDMA(ch32v30x_module *self)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

#ifndef HARDWARE_DISABLE
    DMA_InitTypeDef DMA_InitStructure = {0};
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    DMA_DeInit(TX_DMA_Channel);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART_USED->DATAR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(DebugBuff[0]);
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = UART_TX_BUFF_SIZE;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(TX_DMA_Channel, &DMA_InitStructure);
    DMA_Cmd(TX_DMA_Channel, ENABLE);

    DMA_DeInit(RX_DMA_Channel);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART_USED->DATAR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(UartRxBuff);
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = UART_RX_FIFO_SIZE;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(RX_DMA_Channel, &DMA_InitStructure);
    DMA_Cmd(RX_DMA_Channel, ENABLE);

    USART_DMACmd(USART_USED, USART_DMAReq_Tx, ENABLE);
    USART_DMACmd(USART_USED, USART_DMAReq_Rx, ENABLE);
#endif
}

void ch32v30x_module_v11_InitPwm(ch32v30x_module *self)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

    uint16 n = 0;
    /* For TIM_CounterMode_CenterAligned1 */
    n = (uint16)(self->param_pwm_period_s * 0.5 * self->sysclk_hz) / 65536UL;
    self->pwm_period_count = (uint16)(self->param_pwm_period_s * 0.5 * self->sysclk_hz / (n + 1));
    /* For TIM_CounterMode_Up */
    // n = (uint16)(self->param_pwm_period_s * 1 * self->sysclk_hz) / 65536UL;
    // self->pwm_period_count = (uint16)(self->param_pwm_period_s * 1 * self->sysclk_hz / (n + 1));
#ifndef HARDWARE_DISABLE
    // FLASH->OBR &= ((int16)0x3 << 8);
    // FLASH->OBR |= ((int16)0x3 << 8);

    /*********** Timmer PWM config ***********/
    /* Tim1 Pwm */
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    TIM_OCInitTypeDef TIM_OCInitStructure = {0};
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};
    NVIC_InitTypeDef NVIC_InitStructure = {0};

    /* peripheral clock config */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
    // RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    /* afio config */
    // GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE);

    /* gpio mode config */
    /** board pin custom settings*/
    // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_10;
    // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    // GPIO_Init(GPIOE, &GPIO_InitStructure);

    /** pwm pin init */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* PWM channel output config */
    TIM_TimeBaseInitStructure.TIM_Period = self->pwm_period_count;
    TIM_TimeBaseInitStructure.TIM_Prescaler = n;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; // TIM_CounterMode_Up; //
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = self->pwm_period_count;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // TIM_OCPolarity_Low;//
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = self->pwm_period_count;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // TIM_OCPolarity_Low;//
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = self->pwm_period_count;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // TIM_OCPolarity_Low;//
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = self->pwm_period_count;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // TIM_OCPolarity_Low;//
    TIM_OC4Init(TIM1, &TIM_OCInitStructure);

    /* interrupt config */
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* enable preload */
    // TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable);
    // TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Disable);
    // TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Disable);
    // TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Disable);
    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
    TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
    TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);

    /* enable aoto reload */
    TIM_ARRPreloadConfig(TIM1, ENABLE);

    /* Enable PWM output */
    TIM_CtrlPWMOutputs(TIM1, ENABLE);
    TIM_Cmd(TIM1, DISABLE);

    TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);
#endif
}

void ch32v30x_module_v11_InitTimmer(ch32v30x_module *self)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

#ifndef HARDWARE_DISABLE

#endif
}

void ch32v30x_module_v11_InitSpi(ch32v30x_module *self)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

#ifndef HARDWARE_DISABLE
    //    GPIO_InitTypeDef GPIO_InitStructure = {0};
    SPI_InitTypeDef SPI_InitStructure = {0};

    /* Clock config */
    // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    // RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    /* Gpio remap */
    // GPIO_PinRemapConfig(GPIO_Remap_SPI1, ENABLE);

    /* Gpio config */
    // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; /* SPI CS */
    // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    // GPIO_Init(GPIOA, &GPIO_InitStructure);
    // GPIO_SetBits(GPIOA, GPIO_Pin_4);

    // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; /* SPI SCK */
    // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    // GPIO_Init(GPIOA, &GPIO_InitStructure);

    // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; /* SPI MISO */
    // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    // GPIO_Init(GPIOA, &GPIO_InitStructure);

    // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; /* SPI MOSI */
    // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    // GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* SPI config */
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI1, &SPI_InitStructure);

    /* SPI enable */
    SPI_Cmd(SPI1, ENABLE);

#endif
}

void ch32v30x_module_v11_InitInternalFlash(ch32v30x_module *self)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

#ifndef HARDWARE_DISABLE
    FLASH_Access_Clock_Cfg(FLASH_Access_SYSTEM_HALF);
#endif
}

void ch32v30x_module_v11_InitInputPulseCounter(ch32v30x_module *self)
{
#ifndef HARDWARE_DISABLE
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;
    //    GPIO_InitTypeDef GPIO_InitStructure = {0};

    /* gpio init */
    // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
    // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    // GPIO_Init(GPIOD, &GPIO_InitStructure);

    // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    // GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* Gpio remap */
    // RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    // GPIO_PinRemapConfig(GPIO_PartialRemap_TIM4, ENABLE);

    /* Tim init mode1 */
    // RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    // TIM_CounterModeConfig(TIM4, TIM_CounterMode_Up);
    // TIM_SetAutoreload(TIM4, self->param_input_pulse_counter_period_count);
    // TIM_ETRClockMode1Config(TIM4, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0);
    // /* GPIOA8 Input as TIM Clock Source */
    // TIM_TIxExternalClockConfig(TIM4, TIM_TIxExternalCLK1Source_TI2, TIM_ICPolarity_BothEdge, 0x4);

    /* **************************** */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);

    TIM_CounterModeConfig(TIM3, TIM_CounterMode_Up);
    TIM_SetAutoreload(TIM3, self->param_input_pulse_counter_period_count);

    /* Tim init mode1 */
    TIM_ETRClockMode1Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, self->param_input_pulse_counter_filter_level);
    if (self->param_input_pulse_counter_trigger_mode == InputPulseTrigger_BothEdge)
    {
        TIM_TIxExternalClockConfig(TIM3, TIM_TIxExternalCLK1Source_TI1ED, TIM_ICPolarity_BothEdge, self->param_input_pulse_counter_filter_level);
    }
    else if (self->param_input_pulse_counter_trigger_mode == InputPulseTrigger_RisingEdge)
    {
        TIM_TIxExternalClockConfig(TIM3, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, self->param_input_pulse_counter_filter_level);
    }
    else if (self->param_input_pulse_counter_trigger_mode == InputPulseTrigger_FallingEdge)
    {
        TIM_TIxExternalClockConfig(TIM3, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Falling, self->param_input_pulse_counter_filter_level);
    }
    else if (self->param_input_pulse_counter_trigger_mode == InputPulseTrigger_Custom)
    {
        TIM_TIxExternalClockConfig(TIM3, TIM_TIxExternalCLK1Source_TI2, TIM_ICPolarity_Rising, self->param_input_pulse_counter_filter_level);
    }
    else
    {
        TIM_TIxExternalClockConfig(TIM3, TIM_TIxExternalCLK1Source_TI1, TIM_ICPolarity_Rising, self->param_input_pulse_counter_filter_level);
    }

    // /* Tim init mode2 */
    // RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    // TIM_CounterModeConfig(TIM3, TIM_CounterMode_Up);
    // TIM_SetAutoreload(TIM3, self->param_input_pulse_counter_period_count);

    // TIM_ETRClockMode2Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x08);
    // TIM_SelectInputTrigger(TIM3, TIM_TS_ETRF);

#endif
}

void ch32v30x_module_v11_InitExternalInterrupt(ch32v30x_module *self)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

#ifndef HARDWARE_DISABLE
    //    GPIO_InitTypeDef GPIO_InitStructure = {0};
    EXTI_InitTypeDef EXTI_InitStructure = {0};
    NVIC_InitTypeDef NVIC_InitStructure = {0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    // GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource8);
    EXTI_InitStructure.EXTI_Line = EXTI_Line8;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

#endif
}

void ch32v30x_module_v11_InitIWDG(ch32v30x_module *self)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

#ifndef HARDWARE_DISABLE
    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
    IWDG_SetPrescaler(IWDG_Prescaler_4);
    IWDG_SetReload(1 * 10); // n ms;
    IWDG_ReloadCounter();
#endif
}

void ch32v30x_module_v11_InitWWDG(ch32v30x_module *self)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

#ifndef HARDWARE_DISABLE
    //    NVIC_InitTypeDef NVIC_InitStructure = {0};

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);

    WWDG_SetCounter(0x7f);
    WWDG_SetPrescaler(WWDG_Prescaler_1);
    WWDG_SetWindowValue(0x5f);
    WWDG_ClearFlag();

    // NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;
    // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    // NVIC_Init(&NVIC_InitStructure);

    // WWDG_EnableIT();
#endif
}

void ch32v30x_module_v11_InitDelay(ch32v30x_module *self)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

    self->us_count = self->sysclk_hz / (8 * 1000000);
    self->ms_count = (uint16_t)self->us_count * 1000;
}

void ch32v30x_module_v11_GpioToggle(uint16 gpio)
{
#ifndef HARDWARE_DISABLE
    uint16 gpio_port = gpio / 16;
    uint16 gpio_pin = gpio % 16;

    switch (gpio_port)
    {
    case 0:
        GPIO_WriteBit(GPIOA, 0x1 << gpio_pin, !GPIO_ReadInputDataBit(GPIOA, 0x1 << gpio_pin));
        break;
    case 1:
        GPIO_WriteBit(GPIOB, 0x1 << gpio_pin, !GPIO_ReadInputDataBit(GPIOB, 0x1 << gpio_pin));
        break;
    case 2:
        GPIO_WriteBit(GPIOC, 0x1 << gpio_pin, !GPIO_ReadInputDataBit(GPIOC, 0x1 << gpio_pin));
        break;
    case 3:
        GPIO_WriteBit(GPIOD, 0x1 << gpio_pin, !GPIO_ReadInputDataBit(GPIOD, 0x1 << gpio_pin));
        break;
    case 4:
        GPIO_WriteBit(GPIOE, 0x1 << gpio_pin, !GPIO_ReadInputDataBit(GPIOE, 0x1 << gpio_pin));
        break;
    // case 5:
    //     GPIO_WriteBit(GPIOF, 0x1 << gpio_pin, !GPIO_ReadInputDataBit(GPIOF, 0x1 << gpio_pin));
    //     break;
    // case 6:
    //     GPIO_WriteBit(GPIOG, 0x1 << gpio_pin, !GPIO_ReadInputDataBit(GPIOG, 0x1 << gpio_pin));
    //     break;
    default:
        break;
    }

#endif
}

void ch32v30x_module_v11_GpioSet(uint16 gpio)
{
#ifndef HARDWARE_DISABLE
    uint16 gpio_port = gpio / 16;
    uint16 gpio_pin = gpio % 16;

    switch (gpio_port)
    {
    case 0:
        GPIO_WriteBit(GPIOA, 0x1 << gpio_pin, SET);
        break;
    case 1:
        GPIO_WriteBit(GPIOB, 0x1 << gpio_pin, SET);
        break;
    case 2:
        GPIO_WriteBit(GPIOC, 0x1 << gpio_pin, SET);
        break;
    case 3:
        GPIO_WriteBit(GPIOD, 0x1 << gpio_pin, SET);
        break;
    case 4:
        GPIO_WriteBit(GPIOE, 0x1 << gpio_pin, SET);
        break;
    // case 5:
    //     GPIO_WriteBit(GPIOF, 0x1 << gpio_pin, SET);
    //     break;
    // case 6:
    //     GPIO_WriteBit(GPIOG, 0x1 << gpio_pin, SET);
    // break;
    default:
        break;
    }

#endif
}

void ch32v30x_module_v11_GpioReset(uint16 gpio)
{
#ifndef HARDWARE_DISABLE

    uint16 gpio_port = gpio / 16;
    uint16 gpio_pin = gpio % 16;

    switch (gpio_port)
    {
    case 0:
        GPIO_WriteBit(GPIOA, 0x1 << gpio_pin, RESET);
        break;
    case 1:
        GPIO_WriteBit(GPIOB, 0x1 << gpio_pin, RESET);
        break;
    case 2:
        GPIO_WriteBit(GPIOC, 0x1 << gpio_pin, RESET);
        break;
    case 3:
        GPIO_WriteBit(GPIOD, 0x1 << gpio_pin, RESET);
        break;
    case 4:
        GPIO_WriteBit(GPIOE, 0x1 << gpio_pin, RESET);
        break;
    // case 5:
    //     GPIO_WriteBit(GPIOF, 0x1 << gpio_pin, RESET);
    //     break;
    // case 6:
    //     GPIO_WriteBit(GPIOG, 0x1 << gpio_pin, RESET);
    //     break;
    default:
        break;
    }

#endif
}

uint16 ch32v30x_module_v11_GpioRead(uint16 gpio)
{
    uint16 value = 1;

#ifndef HARDWARE_DISABLE
    uint16 gpio_port = gpio / 16;
    uint16 gpio_pin = gpio % 16;

    switch (gpio_port)
    {
    case 0:
        value = GPIO_ReadInputDataBit(GPIOA, 0x1 << gpio_pin);
        break;
    case 1:
        value = GPIO_ReadInputDataBit(GPIOB, 0x1 << gpio_pin);
        break;
    case 2:
        value = GPIO_ReadInputDataBit(GPIOC, 0x1 << gpio_pin);
        break;
    case 3:
        value = GPIO_ReadInputDataBit(GPIOD, 0x1 << gpio_pin);
        break;
    case 4:
        value = GPIO_ReadInputDataBit(GPIOE, 0x1 << gpio_pin);
        break;
    // case 5:
    //     value = GPIO_ReadInputDataBit(GPIOF, 0x1 << gpio_pin);
    //     break;
    // case 6:
    //     value = GPIO_ReadInputDataBit(GPIOG, 0x1 << gpio_pin);
    //     break;
    default:
        break;
    }

#endif
    return value;
}

void ch32v30x_module_v11_DelayMs(ch32v30x_module *self, uint16 x_ms)
{
#ifndef HARDWARE_DISABLE
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;
    uint32_t i;

    SysTick->SR &= ~(1 << 0);
    i = (uint32_t)x_ms * self->ms_count;

    SysTick->CMP = i;
    SysTick->CTLR |= (1 << 4);
    SysTick->CTLR |= (1 << 5) | (1 << 0);

    while ((SysTick->SR & (1 << 0)) != (1 << 0))
        ;
    SysTick->CTLR &= ~(1 << 0);
#endif
}

void ch32v30x_module_v11_DelayUs(ch32v30x_module *self, uint16 x_us)
{
#ifndef HARDWARE_DISABLE
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;
    uint32_t i;

    SysTick->SR &= ~(1 << 0);
    i = (uint32_t)x_us * self->us_count;

    SysTick->CMP = i;
    SysTick->CTLR |= (1 << 4);
    SysTick->CTLR |= (1 << 5) | (1 << 0);

    while ((SysTick->SR & (1 << 0)) != (1 << 0))
        ;
    SysTick->CTLR &= ~(1 << 0);
#endif
}

int16 ch32v30x_module_v11_AdcGetResult(uint16 adc_num, uint16 channel)
{
    int16 val = 0;
#ifndef HARDWARE_DISABLE
    ADC_TypeDef *adc;

    switch (adc_num)
    {
    case ADC_NUM1:
        adc = ADC1;
        break;
    case ADC_NUM2:
        adc = ADC2;
        break;
    default:
        adc = ADC1;
        break;
    }

    switch (channel)
    {
    case ADC_CHANNEL_REGULAR:
        // ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);
        while (!ADC_GetFlagStatus(adc, ADC_FLAG_EOC))
            ;
        val = ADC_GetConversionValue(adc);
        break;
    case ADC_CHANNEL_INJECT_1:
        // ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);
        while (!ADC_GetFlagStatus(adc, ADC_FLAG_JEOC))
            ;
        val = ADC_GetInjectedConversionValue(adc, ADC_InjectedChannel_1);
        break;
    case ADC_CHANNEL_INJECT_2:
        // ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);
        while (!ADC_GetFlagStatus(adc, ADC_FLAG_JEOC))
            ;
        val = ADC_GetInjectedConversionValue(adc, ADC_InjectedChannel_2);
        break;
    case ADC_CHANNEL_INJECT_3:
        // ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);
        while (!ADC_GetFlagStatus(adc, ADC_FLAG_JEOC))
            ;
        val = ADC_GetInjectedConversionValue(adc, ADC_InjectedChannel_3);
        break;
    case ADC_CHANNEL_INJECT_4:
        // ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);
        while (!ADC_GetFlagStatus(adc, ADC_FLAG_JEOC))
            ;
        val = ADC_GetInjectedConversionValue(adc, ADC_InjectedChannel_4);
        break;
    default:
        break;
    }
#endif
    return val;
}

void ch32v30x_module_v11_StartTimmer()
{
#ifndef HARDWARE_DISABLE
    TIM_Cmd(TIM1, ENABLE);
    // TIM_Cmd(TIM4, ENABLE);
    TIM_Cmd(TIM3, ENABLE);

#endif
}

void ch32v30x_module_v11_StopTimmer()
{
#ifndef HARDWARE_DISABLE
    TIM_Cmd(TIM1, DISABLE);
    // TIM_Cmd(TIM4, DISABLE);
    TIM_Cmd(TIM3, DISABLE);
#endif
}

void ch32v30x_module_v11_GpioPinInit(ch32v30x_module *self, uint16 gpio, uint16 gpio_mode)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

#ifndef HARDWARE_DISABLE
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    uint16 gpio_port = gpio / 16;
    uint16 gpio_pin = gpio % 16;

    GPIO_InitStructure.GPIO_Pin = 0x1 << gpio_pin;
    GPIO_InitStructure.GPIO_Mode = self->GpioModeTranslate(gpio_mode);
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    switch (gpio_port)
    {
    case 0:
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        break;
    case 1:
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        break;
    case 2:
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
        GPIO_Init(GPIOC, &GPIO_InitStructure);
        break;
    case 3:
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
        GPIO_Init(GPIOD, &GPIO_InitStructure);
        break;
    case 4:
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
        GPIO_Init(GPIOE, &GPIO_InitStructure);
        break;
        // case 5:
        // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
        //     GPIO_Init(GPIOF, &GPIO_InitStructure);
        //     break;
        // case 6:
        // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);
        //     GPIO_Init(GPIOG, &GPIO_InitStructure);
        break;
    default:
        break;
    }

#endif
}

uint16 ch32v30x_module_v11_GpioModeTranslate(uint16 gpio_mode)
{
#ifndef HARDWARE_DISABLE
    switch (gpio_mode)
    {
    case GPIO_GENERAL_MODE_ANALOG_IN:
        return GPIO_Mode_AIN;
        break;
    case GPIO_GENERAL_MODE_IN_FLOATING:
        return GPIO_Mode_IN_FLOATING;
        break;
    case GPIO_GENERAL_MODE_IN_PULL_DOWN:
        return GPIO_Mode_IPD;
        break;
    case GPIO_GENERAL_MODE_IN_PULL_UP:
        return GPIO_Mode_IPU;
        break;
    case GPIO_GENERAL_MODE_OUT_OPEN_DRAIN:
        return GPIO_Mode_Out_OD;
        break;
    case GPIO_GENERAL_MODE_OUT_PUSH_PULL:
        return GPIO_Mode_Out_PP;
        break;
    case GPIO_GENERAL_MODE_AF_OPEN_DRAIN:
        return GPIO_Mode_AF_OD;
        break;
    case GPIO_GENERAL_MODE_AF_PUSH_PULL:
        return GPIO_Mode_AF_PP;
        break;
    default:
        return GPIO_Mode_AIN;
        break;
    }
#endif
    return 0;
}

void ch32v30x_module_v11_SetPwm(ch32v30x_module *self, uint16 pwm_channel, float32 pwm_duty)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

    // DBprintf("%s\t ", float2str(pwm_duty, 4));
    // self->pwm_period_count = 2880;
    // DBprintf("%d\t ", self->pwm_period_count);
    // DBprintf("%s\t ", float2str((uint16)self->pwm_period_count * pwm_duty, 4));

    switch (pwm_channel)
    {
    case 1:
        self->pwm_ch1_cmp_value = (uint16)(self->pwm_period_count * pwm_duty);
        break;
    case 2:
        self->pwm_ch2_cmp_value = (uint16)(self->pwm_period_count * pwm_duty);
        break;
    case 3:
        self->pwm_ch3_cmp_value = (uint16)(self->pwm_period_count * pwm_duty);
        break;
    case 4:
        self->pwm_ch4_cmp_value = (uint16)(self->pwm_period_count * pwm_duty);
        break;
    case 5:
        // pwm_duty_count = (uint16)(self->pwm_period_count * pwm_duty);
        // TIM_SetCompare3(TIM1, pwm_duty_count);
        break;
    case 6:
        // pwm_duty_count = (uint16)(self->pwm_period_count * pwm_duty);
        // TIM_SetCompare4(TIM1, pwm_duty_count);
        break;

    default:
        break;
    }

#ifndef HARDWARE_DISABLE

    switch (pwm_channel)
    {
    case 1:
        // TIM_SetCompare1(TIM1, self->pwm_ch1_cmp_value);
        TIM1->CH1CVR = self->pwm_ch1_cmp_value;
        break;
    case 2:
        // TIM_SetCompare2(TIM1, self->pwm_ch2_cmp_value);
        TIM1->CH2CVR = self->pwm_ch2_cmp_value;
        break;
    case 3:
        // TIM_SetCompare3(TIM1, self->pwm_ch3_cmp_value);
        TIM1->CH3CVR = self->pwm_ch3_cmp_value;
        break;
    case 4:
        // TIM_SetCompare4(TIM1, self->pwm_ch4_cmp_value);
        TIM1->CH4CVR = self->pwm_ch4_cmp_value;
        break;
    case 5:
        // pwm_duty_count = (uint16)(self->pwm_period_count * pwm_duty);
        // TIM_SetCompare3(TIM1, pwm_duty_count);
        break;
    case 6:
        // pwm_duty_count = (uint16)(self->pwm_period_count * pwm_duty);
        // TIM_SetCompare4(TIM1, pwm_duty_count);
        break;

    default:
        break;
    }
#endif
}

void ch32v30x_module_v11_SetAllPwm(ch32v30x_module *self, float32 pwm_duty_ch1, float32 pwm_duty_ch2, float32 pwm_duty_ch3, float32 pwm_duty_ch4)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

    self->pwm_ch1_cmp_value = (uint16)(self->pwm_period_count * pwm_duty_ch1);
    self->pwm_ch2_cmp_value = (uint16)(self->pwm_period_count * pwm_duty_ch2);
    self->pwm_ch3_cmp_value = (uint16)(self->pwm_period_count * pwm_duty_ch3);
    self->pwm_ch4_cmp_value = (uint16)(self->pwm_period_count * pwm_duty_ch4);
#ifndef HARDWARE_DISABLE
    TIM1->CH1CVR = self->pwm_ch1_cmp_value;
    TIM1->CH2CVR = self->pwm_ch2_cmp_value;
    TIM1->CH3CVR = self->pwm_ch3_cmp_value;
    TIM1->CH4CVR = self->pwm_ch4_cmp_value;
#endif
}

uint8 ch32v30x_module_v11_SPI_WriteReadData(uint16 *write_data, uint8 *read_data, uint16 data_len, uint16 over_time)
{

#ifndef HARDWARE_DISABLE
    uint8 read_count = 0;
    uint8 write_count = 0;
    uint16 time_count = 0;

    SPI_CS_L();

    __disable_irq();
    while (((write_count < data_len) || (read_count < data_len)) && (time_count < over_time))
    {
        if (write_count < data_len)
        {
            // if (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != RESET)
            if ((SPI1->STATR & SPI_I2S_FLAG_TXE) != (uint16_t)RESET)
            {
                // SPI_I2S_SendData(SPI1, write_data[write_count]);
                SPI1->DATAR = write_data[write_count];
                write_count++;
            }
        }
        if (read_count < data_len)
        {
            // if (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != RESET)
            if ((SPI1->STATR & SPI_I2S_FLAG_RXNE) != (uint16_t)RESET)
            {
                // read_data[read_count] = SPI_I2S_ReceiveData(SPI1);
                read_data[data_len - read_count - 1] = (uint8)SPI1->DATAR;
                read_count++;
            }
        }
        time_count++;
    }
    __enable_irq();

    if (time_count >= over_time)
    {
        return 0;
    }

    // while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) != RESET)
    // Delay_Us(1);
    SPI_CS_H();

#endif

    return 1;
}

uint8 ch32v30x_module_v11_SPI_WriteReg(uint8 addr, uint8 *data, uint16 data_len)
{
    uint8 i = 0;

#ifndef HARDWARE_DISABLE

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
        ;
    SPI_I2S_SendData(SPI1, addr & ~0x80);

    for (i = 0; i < data_len; i++)
    {
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
            ;
        SPI_I2S_SendData(SPI1, data[i]);
    }
#endif

    return i;
}

uint8 ch32v30x_module_v11_SPI_ReadReg(uint8 addr, uint8 *data, uint16 data_len)
{

#ifndef HARDWARE_DISABLE
    uint8 read_count = 0;
    uint8 write_count = 0;
    uint8 writebuff[4] = {0};
    //    uint8 readbuff[4] = {0};

    writebuff[0] = 0x03 | 0x80;
    writebuff[1] = 0x00;
    writebuff[2] = 0x04 | 0x80;
    writebuff[3] = 0x00;

    // while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
    //     ;
    // SPI_I2S_SendData(SPI1, addr | 0x80);

    // while ((write_count < 4)||(read_count < 4))

    SPI_CS_L();
    while ((write_count < 4))
    {
        if (write_count < 4)
        {
            if (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != RESET)
            {
                SPI_I2S_SendData(SPI1, writebuff[write_count]);
                write_count++;
            }
        }
        if (read_count < 4)
        {
            if (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != RESET)
            {
                data[read_count] = SPI_I2S_ReceiveData(SPI1);
                read_count++;
            }
        }
    }

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) != RESET)
        SPI_CS_H();
        // for (i = 0; i < data_len; )
        // {
        //     if(){

        //     }
        //     while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)
        //         ;
        //     data[i] = SPI_I2S_ReceiveData(SPI1);
        // }
#endif

    return 0;
}

uint8 ch32v30x_module_v11_SPI_WriteByte(uint8 data)
{
#ifndef HARDWARE_DISABLE

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
        ;
    SPI_I2S_SendData(SPI1, data);
#endif
    return 1;
}

uint8 ch32v30x_module_v11_SPI_ReadByte()
{
    uint8 data = 0;

#ifndef HARDWARE_DISABLE
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)
        ;
    data = SPI_I2S_ReceiveData(SPI1);
#endif
    return data;
}

void ch32v30x_module_v11_EnableInterrupt()
{
#ifndef HARDWARE_DISABLE
    TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
#endif
}

void ch32v30x_module_v11_EnableNvicInterrupt()
{
#ifndef HARDWARE_DISABLE
    NVIC_EnableIRQ(TIM1_UP_IRQn);
    NVIC_EnableIRQ(EXTI4_IRQn);
#endif
}

void ch32v30x_module_v11_DisableNvicInterrupt()
{
#ifndef HARDWARE_DISABLE
    NVIC_DisableIRQ(TIM1_UP_IRQn);
    NVIC_DisableIRQ(EXTI4_IRQn);
#endif
}

void ch32v30x_module_v11_ADC_StartConversion()
{
#ifndef HARDWARE_DISABLE
    // ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);
    ADC1->CTLR2 |= ((uint32_t)0x00208000);
#endif
}

void ch32v30x_module_v11_ADC_WaitConversionComplete()
{
#ifndef HARDWARE_DISABLE

    while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_JEOC))
    {
    }
#endif
}

void ch32v30x_module_v11_FlashWriteOnePage256Bytes(uint32 flash_start_addr, uint32 addr_n_256, uint32 *data_buff)
{
#ifndef HARDWARE_DISABLE

    FLASH_ProgramPage_Fast(flash_start_addr + 256UL * addr_n_256, data_buff);

#endif
}

void ch32v30x_module_v11_FlashWriteHalfWord(uint32 flash_start_addr, uint32 data_addr_offset, uint16 data)
{
#ifndef HARDWARE_DISABLE

    uint32 addr = flash_start_addr + data_addr_offset;
    FLASH_ProgramHalfWord(addr, data);

#endif
}

void ch32v30x_module_v11_FlashEraseOnePage256Bytes_Fast(uint32 flash_start_addr, uint32 addr_n_256)
{
#ifndef HARDWARE_DISABLE
    FLASH_ErasePage_Fast(flash_start_addr + 256UL * addr_n_256);
#endif
}

void ch32v30x_module_v11_FlashEraseOnePage32KBytes_Fast(uint32 flash_start_addr, uint32 addr_n_32k)
{
#ifndef HARDWARE_DISABLE
    FLASH_EraseBlock_32K_Fast(flash_start_addr + addr_n_32k * 0x400);
#endif
}

void ch32v30x_module_v11_FlashEraseOnePage32KBytes(uint32 flash_start_addr, uint32 flash_end_addr)
{
#ifndef HARDWARE_DISABLE

///* Global Variable */
// uint32_t EraseCounter = 0x0, Address = 0x0;
// uint16_t Data = 0xAAAA;
// uint32_t WRPR_Value = 0xFFFFFFFF, ProtectedPages = 0x0;
// uint32_t NbrOfPage;
// volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;
// volatile TestStatus MemoryProgramStatus = PASSED;
// volatile TestStatus MemoryEraseStatus = PASSED;
// u32 buf[64];

//    NbrOfPage = (flash_end_addr - flash_start_addr) / FLASH_PAGE_SIZE;
//
//    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_WRPRTERR);
//
//    for (EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
//    {
//        FLASHStatus = FLASH_ErasePage(flash_start_addr + (FLASH_PAGE_SIZE * EraseCounter)); // Erase 4KB
//
//        if (FLASHStatus != FLASH_COMPLETE)
//        {
//            printf("FLASH Erase Fail\r\n");
//        }
//        printf("FLASH Erase Suc\r\n");
//    }
#endif
}

void ch32v30x_module_v11_FlashUnlockFast()
{
#ifndef HARDWARE_DISABLE
    FLASH_Unlock_Fast();
#endif
}

void ch32v30x_module_v11_FlashLockFast()
{
#ifndef HARDWARE_DISABLE
    FLASH_Lock_Fast();
#endif
}

void ch32v30x_module_v11_FlashUnlock()
{
#ifndef HARDWARE_DISABLE
    FLASH_Unlock();
#endif
}

void ch32v30x_module_v11_FlashLock()
{
#ifndef HARDWARE_DISABLE
    FLASH_Lock();
#endif
}

void ch32v30x_module_v11_FlashClearFlag()
{
#ifndef HARDWARE_DISABLE
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_WRPRTERR);
#endif
}

uint16_t ch32v30x_module_v11_GetInputPulseCounter()
{
    uint16_t ret = 0;
#ifndef HARDWARE_DISABLE
    // ret = TIM_GetCounter(TIM4);
    ret = TIM_GetCounter(TIM3);
#endif
    return ret;
}

void ch32v30x_module_v11_ClearInputPulseCounter()
{
#ifndef HARDWARE_DISABLE
    TIM4->CNT = 0;
#endif
}

void ch32v30x_module_v11_SetInputPulseCounter(uint16_t count)
{
#ifndef HARDWARE_DISABLE
    // TIM_SetCounter(TIM4, count);
    TIM_SetCounter(TIM3, count);
#endif
}

void ch32v30x_module_v11_EnableInputPulseCounter()
{
#ifndef HARDWARE_DISABLE
    // TIM_Cmd(TIM4, ENABLE);
    TIM_Cmd(TIM3, ENABLE);
#endif
}
void ch32v30x_module_v11_AddInputPulseCounter(uint16_t count)
{
#ifndef HARDWARE_DISABLE
    TIM4->CNT += count;
#endif
}

void ch32v30x_module_v11_DisableInputPulseCounter()
{
#ifndef HARDWARE_DISABLE
    // TIM_Cmd(TIM4, DISABLE);
    TIM_Cmd(TIM3, DISABLE);
#endif
}

void ch32v30x_module_v11_StartUartDMA()
{
#ifndef HARDWARE_DISABLE
    USART_DMACmd(USART_USED, USART_DMAReq_Tx, ENABLE);
#endif
}

uint8 ch32v30x_module_v11_UartReceiveOnePackFinished(ch32v30x_module *self, uint16 *data_len)
{
    //    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

    uint8 receive_ok = 0;
#ifndef HARDWARE_DISABLE
    uint8 data = 0;
    if (USART_GetFlagStatus(USART_USED, USART_FLAG_IDLE))
    {
        data = USART_ReceiveData(USART_USED); /* read data_reg to clear IDLE flag */
        DMA_ClearFlag(DMA1_IT_TC3);
        DMA_Cmd(RX_DMA_Channel, DISABLE);

        *data_len = UART_RX_FIFO_SIZE - DMA_GetCurrDataCounter(RX_DMA_Channel);

        receive_ok = 1;
        DMA_SetCurrDataCounter(RX_DMA_Channel, UART_RX_FIFO_SIZE);
        DMA_Cmd(RX_DMA_Channel, ENABLE);
    }
#endif
    return receive_ok;
}

void ch32v30x_module_v11_ResetSystem()
{
#ifndef HARDWARE_DISABLE
    /* reset periph */
    RCC_APB1PeriphResetCmd(0xffffffff, 1);
    RCC_APB2PeriphResetCmd(0xffffffff, 1);
    RCC_APB1PeriphResetCmd(0xffffffff, 0);
    RCC_APB2PeriphResetCmd(0xffffffff, 0);
#endif
}

void ch32v30x_module_v11_InitPinNum(ch32v30x_module *self)
{
    ch32v30x_module_v11 *_ = (ch32v30x_module_v11 *)self->_;

    /* init pin */
    if (NULL != _->param_pin_PA0)
        _->param_pin_PA0->pin = 0;
    if (NULL != _->param_pin_PA1)
        _->param_pin_PA1->pin = 1;
    if (NULL != _->param_pin_PA2)
        _->param_pin_PA2->pin = 2;
    if (NULL != _->param_pin_PA3)
        _->param_pin_PA3->pin = 3;
    if (NULL != _->param_pin_PA4)
        _->param_pin_PA4->pin = 4;
    if (NULL != _->param_pin_PA5)
        _->param_pin_PA5->pin = 5;
    if (NULL != _->param_pin_PA6)
        _->param_pin_PA6->pin = 6;
    if (NULL != _->param_pin_PA7)
        _->param_pin_PA7->pin = 7;
    if (NULL != _->param_pin_PA8)
        _->param_pin_PA8->pin = 8;
    if (NULL != _->param_pin_PA9)
        _->param_pin_PA9->pin = 9;
    if (NULL != _->param_pin_PA10)
        _->param_pin_PA10->pin = 10;
    if (NULL != _->param_pin_PA11)
        _->param_pin_PA11->pin = 11;
    if (NULL != _->param_pin_PA12)
        _->param_pin_PA12->pin = 12;
    if (NULL != _->param_pin_PA13)
        _->param_pin_PA13->pin = 13;
    if (NULL != _->param_pin_PA14)
        _->param_pin_PA14->pin = 14;
    if (NULL != _->param_pin_PA15)
        _->param_pin_PA15->pin = 15;
    if (NULL != _->param_pin_PB0)
        _->param_pin_PB0->pin = 16 * 1 + 0;
    if (NULL != _->param_pin_PB1)
        _->param_pin_PB1->pin = 16 * 1 + 1;
    if (NULL != _->param_pin_PB2)
        _->param_pin_PB2->pin = 16 * 1 + 2;
    if (NULL != _->param_pin_PB3)
        _->param_pin_PB3->pin = 16 * 1 + 3;
    if (NULL != _->param_pin_PB4)
        _->param_pin_PB4->pin = 16 * 1 + 4;
    if (NULL != _->param_pin_PB5)
        _->param_pin_PB5->pin = 16 * 1 + 5;
    if (NULL != _->param_pin_PB6)
        _->param_pin_PB6->pin = 16 * 1 + 6;
    if (NULL != _->param_pin_PB7)
        _->param_pin_PB7->pin = 16 * 1 + 7;
    if (NULL != _->param_pin_PB8)
        _->param_pin_PB8->pin = 16 * 1 + 8;
    if (NULL != _->param_pin_PB9)
        _->param_pin_PB9->pin = 16 * 1 + 9;
    if (NULL != _->param_pin_PB10)
        _->param_pin_PB10->pin = 16 * 1 + 10;
    if (NULL != _->param_pin_PB11)
        _->param_pin_PB11->pin = 16 * 1 + 11;
    if (NULL != _->param_pin_PB12)
        _->param_pin_PB12->pin = 16 * 1 + 12;
    if (NULL != _->param_pin_PB13)
        _->param_pin_PB13->pin = 16 * 1 + 13;
    if (NULL != _->param_pin_PB14)
        _->param_pin_PB14->pin = 16 * 1 + 14;
    if (NULL != _->param_pin_PB15)
        _->param_pin_PB15->pin = 16 * 1 + 15;
    if (NULL != _->param_pin_PC0)
        _->param_pin_PC0->pin = 16 * 2 + 0;
    if (NULL != _->param_pin_PC1)
        _->param_pin_PC1->pin = 16 * 2 + 1;
    if (NULL != _->param_pin_PC2)
        _->param_pin_PC2->pin = 16 * 2 + 2;
    if (NULL != _->param_pin_PC3)
        _->param_pin_PC3->pin = 16 * 2 + 3;
    if (NULL != _->param_pin_PC4)
        _->param_pin_PC4->pin = 16 * 2 + 4;
    if (NULL != _->param_pin_PC5)
        _->param_pin_PC5->pin = 16 * 2 + 5;
    if (NULL != _->param_pin_PC6)
        _->param_pin_PC6->pin = 16 * 2 + 6;
    if (NULL != _->param_pin_PC7)
        _->param_pin_PC7->pin = 16 * 2 + 7;
    if (NULL != _->param_pin_PC8)
        _->param_pin_PC8->pin = 16 * 2 + 8;
    if (NULL != _->param_pin_PC9)
        _->param_pin_PC9->pin = 16 * 2 + 9;
    if (NULL != _->param_pin_PC10)
        _->param_pin_PC10->pin = 16 * 2 + 10;
    if (NULL != _->param_pin_PC11)
        _->param_pin_PC11->pin = 16 * 2 + 11;
    if (NULL != _->param_pin_PC12)
        _->param_pin_PC12->pin = 16 * 2 + 12;
    if (NULL != _->param_pin_PC13)
        _->param_pin_PC13->pin = 16 * 2 + 13;
    if (NULL != _->param_pin_PC14)
        _->param_pin_PC14->pin = 16 * 2 + 14;
    if (NULL != _->param_pin_PC15)
        _->param_pin_PC15->pin = 16 * 2 + 15;
    if (NULL != _->param_pin_PD0)
        _->param_pin_PD0->pin = 16 * 3 + 0;
    if (NULL != _->param_pin_PD1)
        _->param_pin_PD1->pin = 16 * 3 + 1;
    if (NULL != _->param_pin_PD2)
        _->param_pin_PD2->pin = 16 * 3 + 2;
    if (NULL != _->param_pin_PD3)
        _->param_pin_PD3->pin = 16 * 3 + 3;
    if (NULL != _->param_pin_PD4)
        _->param_pin_PD4->pin = 16 * 3 + 4;
    if (NULL != _->param_pin_PD5)
        _->param_pin_PD5->pin = 16 * 3 + 5;
    if (NULL != _->param_pin_PD6)
        _->param_pin_PD6->pin = 16 * 3 + 6;
    if (NULL != _->param_pin_PD7)
        _->param_pin_PD7->pin = 16 * 3 + 7;
    if (NULL != _->param_pin_PD8)
        _->param_pin_PD8->pin = 16 * 3 + 8;
    if (NULL != _->param_pin_PD9)
        _->param_pin_PD9->pin = 16 * 3 + 9;
    if (NULL != _->param_pin_PD10)
        _->param_pin_PD10->pin = 16 * 3 + 10;
    if (NULL != _->param_pin_PD11)
        _->param_pin_PD11->pin = 16 * 3 + 11;
    if (NULL != _->param_pin_PD12)
        _->param_pin_PD12->pin = 16 * 3 + 12;
    if (NULL != _->param_pin_PD13)
        _->param_pin_PD13->pin = 16 * 3 + 13;
    if (NULL != _->param_pin_PD14)
        _->param_pin_PD14->pin = 16 * 3 + 14;
    if (NULL != _->param_pin_PD15)
        _->param_pin_PD15->pin = 16 * 3 + 15;
    if (NULL != _->param_pin_PE0)
        _->param_pin_PE0->pin = 16 * 4 + 0;
    if (NULL != _->param_pin_PE1)
        _->param_pin_PE1->pin = 16 * 4 + 1;
    if (NULL != _->param_pin_PE2)
        _->param_pin_PE2->pin = 16 * 4 + 2;
    if (NULL != _->param_pin_PE3)
        _->param_pin_PE3->pin = 16 * 4 + 3;
    if (NULL != _->param_pin_PE4)
        _->param_pin_PE4->pin = 16 * 4 + 4;
    if (NULL != _->param_pin_PE5)
        _->param_pin_PE5->pin = 16 * 4 + 5;
    if (NULL != _->param_pin_PE6)
        _->param_pin_PE6->pin = 16 * 4 + 6;
    if (NULL != _->param_pin_PE7)
        _->param_pin_PE7->pin = 16 * 4 + 7;
    if (NULL != _->param_pin_PE8)
        _->param_pin_PE8->pin = 16 * 4 + 8;
    if (NULL != _->param_pin_PE9)
        _->param_pin_PE9->pin = 16 * 4 + 9;
    if (NULL != _->param_pin_PE10)
        _->param_pin_PE10->pin = 16 * 4 + 10;
    if (NULL != _->param_pin_PE11)
        _->param_pin_PE11->pin = 16 * 4 + 11;
    if (NULL != _->param_pin_PE12)
        _->param_pin_PE12->pin = 16 * 4 + 12;
    if (NULL != _->param_pin_PE13)
        _->param_pin_PE13->pin = 16 * 4 + 13;
    if (NULL != _->param_pin_PE14)
        _->param_pin_PE14->pin = 16 * 4 + 14;
    if (NULL != _->param_pin_PE15)
        _->param_pin_PE15->pin = 16 * 4 + 15;
}

// void ch32v30x_module_v11_InitPinNum(ch32v30x_module *self)
void ch32v30x_module_v11_UartDMASend(uint8_t *data, uint8_t len)
{
#ifndef HARDWARE_DISABLE
    DMA_Cmd(TX_DMA_Channel, DISABLE);
    TX_DMA_Channel->MADDR = (u32)(data);
    TX_DMA_Channel->CNTR = len;
    DMA_Cmd(TX_DMA_Channel, ENABLE);
#endif
}

void ch32v30x_module_v11_SetInputPulseCouterCountUp()
{
#ifndef HARDWARE_DISABLE
    // TIM_CounterModeConfig(TIM4, TIM_CounterMode_Up);
    TIM_CounterModeConfig(TIM3, TIM_CounterMode_Up);
#endif
}

void ch32v30x_module_v11_SetInputPulseCouterCountDown()
{
#ifndef HARDWARE_DISABLE
    // TIM_CounterModeConfig(TIM4, TIM_CounterMode_Down);
    TIM_CounterModeConfig(TIM3, TIM_CounterMode_Down);
#endif
}

void ch32v30x_module_v11_EnableIWDG()
{
#ifndef HARDWARE_DISABLE
    IWDG_Enable();
#endif
}

void ch32v30x_module_v11_EnableWWDG()
{
#ifndef HARDWARE_DISABLE
    WWDG_Enable(0x7f);
#endif
}

void ch32v30x_module_v11_FeedIWDG()
{
#ifndef HARDWARE_DISABLE
    IWDG_ReloadCounter();
#endif
}

void ch32v30x_module_v11_FeedWWDG()
{
#ifndef HARDWARE_DISABLE
    WWDG_SetCounter(0x7f);
#endif
}

void ch32v30x_module_v11_UartSendOneByte(uint16_t data)
{
#ifndef HARDWARE_DISABLE
    while (USART_GetFlagStatus(USART_USED, USART_FLAG_TC) == RESET)
        ;
    USART_SendData(USART_USED, data);
#endif
}

void ch32v30x_module_v11_DMA_Send()
{
#ifndef HARDWARE_DISABLE
    DMA_Cmd(TX_DMA_Channel, DISABLE);
    TX_DMA_Channel->MADDR = (u32)DebugBuff[DebugIndex];
    TX_DMA_Channel->CNTR = strlen(DebugBuff[DebugIndex]);
    DMA_Cmd(TX_DMA_Channel, ENABLE);
    DebugIndex = (DebugIndex + 1) & 0x1;
    DebugBuff[DebugIndex][0] = '\0';
#endif
}

void ch32v30x_module_v11_DMAAdv_Send()
{
#ifndef HARDWARE_DISABLE

    uint16 new_buff_len = 0;
    new_buff_len = strlen(DebugNewDataBuff);
    if (TX_DMA_Channel->CNTR == 0 && new_buff_len == 0)
    {
        DebugBuff[0][0] = '\0';
        DebugBaseIndex = 0;
    }
    else if (TX_DMA_Channel->CNTR == 0 && new_buff_len > 0)
    {
        if (strlen(DebugBuff[0]) + new_buff_len >= UART_TX_BUFF_SIZE)
        {
            DebugBuff[0][0] = '\0';
        }
        DebugBaseIndex = strlen(DebugBuff[0]);
        strcat(DebugBuff[0], DebugNewDataBuff);
        DMA_Cmd(TX_DMA_Channel, DISABLE);
        TX_DMA_Channel->MADDR = (u32)(&(DebugBuff[0][DebugBaseIndex]));
        TX_DMA_Channel->CNTR = new_buff_len;
        DMA_Cmd(TX_DMA_Channel, ENABLE);
        DebugNewDataBuff[0] = '\0';
    }
#endif
}

void ch32v30x_module_v11_DMAHex_Send()
{
#ifndef HARDWARE_DISABLE
    if (TX_DMA_Channel->CNTR == 0 && DebugNewDataBuff_Len == 0)
    {
        DebugBuff_Len = 0;
        DebugBaseIndex = 0;
    }
    else if (TX_DMA_Channel->CNTR == 0 && DebugNewDataBuff_Len > 0)
    {
        if (DebugBuff_Len + DebugNewDataBuff_Len >= UART_TX_BUFF_SIZE)
        {
            DebugBuff_Len = 0;
        }
        DebugBaseIndex = DebugBuff_Len;
        memcpy(&DebugBuff[0][DebugBaseIndex], DebugNewDataBuff, DebugNewDataBuff_Len);
        DebugBuff_Len += DebugNewDataBuff_Len;
        DMA_Cmd(TX_DMA_Channel, DISABLE);
        TX_DMA_Channel->MADDR = (u32)(&(DebugBuff[0][DebugBaseIndex]));
        TX_DMA_Channel->CNTR = DebugNewDataBuff_Len;
        DMA_Cmd(TX_DMA_Channel, ENABLE);
        DebugNewDataBuff_Len = 0;
    }
#endif
}

void ch32v30x_module_v11_JumpToBootLoader()
{
#ifndef HARDWARE_DISABLE
    // NVIC_EnableIRQ(Software_IRQn);
    // NVIC_SetPendingIRQ(Software_IRQn);
#endif
}

void ch32v30x_module_v11_HCLKSetToDiv1()
{
#ifndef HARDWARE_DISABLE
    RCC->CFGR0 &= ~RCC_HPRE;
    RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
#endif
}

void ch32v30x_module_v11_HCLKSetToDiv2()
{
#ifndef HARDWARE_DISABLE
    RCC->CFGR0 &= ~RCC_HPRE;
    RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2;
#endif
}